package com.zjl.spring.第03章_IOC;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * ClassName: E2_获取指定包下的所有类
 * Package: com.zjl.spring.第03章_IOC
 * Description:
 *
 * @Author 张蛟龙
 * @Create 2024/7/19 22:10
 * @Version 1.0
 */
public class E2_获取指定包下的所有类 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        System.setProperty("file.encoding", "UTF-8");
        List<Class<?>> classes = findClasses("com.zjl.spring.第03章_IOC");
        System.out.println("-----以下是包的全路径-----------------------");
        for (Class<?> clazz : classes) {
            System.out.println(clazz.getName());
        }
    }

    public static List<Class<?>> findClasses(String packageName) throws UnsupportedEncodingException {
        List<Class<?>> classes = new ArrayList<>();
        String basePath = packageName.replace(".", "/");//将 . 转为 /
        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();//获取当前线程构造器
        URL resource = contextClassLoader.getResource(basePath);//获取此包的地址
        String path = resource.getPath();//获取此包的绝对路径
        //如果路径含有中文，则无法识别，则需要此类
        String decode = URLDecoder.decode(path, StandardCharsets.UTF_8.toString());
        File directory = new File(decode);//获取此文件的路径
        if (directory.exists()) {
            findClassesInPackage(packageName, directory, classes);
        }
        return classes;
    }

    private static void findClassesInPackage(String packageName, File directory, List<Class<?>> classes) {
        File[] files = directory.listFiles();//获取此路径下的所有文件
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {//如果是文件夹 则递归
                    findClassesInPackage(packageName + "." + file.getName(), file, classes);
                } else if (file.getName().endsWith(".class")) {//如果是class文件则获取 全类名

                    String className = file.getName().substring(0, file.getName().length() - 6);//把文件名的 .class去掉
                    try {
                        classes.add(Class.forName(packageName + "." + className));
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
